// 给你两个长度相同的字符串，s 和 t。

// 将 s 中的第 i 个字符变到 t 中的第 i 个字符需要 |s[i] - t[i]| 的开销（开销可能为 0），
// 也就是两个字符的 ASCII 码值的差的绝对值。

// 用于变更字符串的最大预算是 maxCost。在转化字符串时，总开销应当小于等于该预算，这也意味着字符串的转化可能是不完全的。
// 如果你可以将 s 的子字符串转化为它在 t 中对应的子字符串，则返回可以转化的最大长度。

// 如果 s 中没有子字符串可以转化成 t 中对应的子字符串，则返回 0。

// 暴露接口
const equalSubstring = function (s: string, t: string, maxCost: number): number {
    // 声明的窗口区间为左闭右闭
    let left = 0;
    let right = 0;
    let res = 0; // 结果长度
    while (right < s.length) {
        const currCost = equalSubstring_calCost(s, t, right);
        maxCost -= currCost;
        // 如果超出费用限制，缩小窗口并返还费用
        if (maxCost < 0) {
            maxCost += equalSubstring_calCost(s, t, left);
            left++;
        }
        // 维护结果长度
        res = Math.max(res, right - left + 1);
        right++;
    }
    return res;
};
// 辅助方法：用于计算ASCII码值相减的费用
function equalSubstring_calCost(s: string, t: string, index: number): number {
    return Math.abs(s[index].charCodeAt(0) - t[index].charCodeAt(0));
}


// 这道题目也是一道比较典型的通过滑动窗口解决的问题
// 首先题目要求看着比较抽象也比较唬人，但实际上经过封装可以简化理解题目的心智负担
// 计算费用的方式实际就是求两个字符的 ASCII 码值的差的绝对值。
// 我们先声明一个滑动窗口，起始大小为1-->左闭右闭
// 我们在滑动窗口的过程中动态地计算当前的字符替换费用，然后用最大限度开销减去替换费用
// 也就是动态地维护 maxCost ，如果当前轮次下 maxCost >= 0，那么无事情发生
// 但若 maxCost < 0,说明费用现在不够了，我们需要右移左边界并“归还”费用，
// 因为 maxCost 的初始值一定大于等于0，所以不用担心左指针右移后超过右指针导致cost出现负数的情况
// 然后我们在每一轮的结束前都右移右指针，并维护结果长度
// 等待滑窗走完整个字符串后即可得到结果。